package com.micro.ai.auth.service.impl;

import com.micro.ai.auth.service.TokenBlacklistService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.ReactiveRedisTemplate;
import org.springframework.stereotype.Service;

import java.time.Duration;

/**
 * 令牌黑名单服务实现
 * 
 * @author micro-ai
 * @since 0.0.1
 */
@Slf4j
@Service
public class TokenBlacklistServiceImpl implements TokenBlacklistService {

    @Autowired
    private ReactiveRedisTemplate<String, String> reactiveRedisTemplate;

    private static final String BLACKLIST_PREFIX = "token:blacklist:";

    @Override
    public void addToBlacklist(String token, long expiresIn) {
        try {
            String key = BLACKLIST_PREFIX + token;
            Duration duration = Duration.ofSeconds(expiresIn);
            reactiveRedisTemplate.opsForValue()
                    .set(key, "1", duration)
                    .doOnSuccess(result -> log.info("令牌已加入黑名单: token={}, expiresIn={}s", 
                        token.substring(0, Math.min(20, token.length())) + "...", expiresIn))
                    .doOnError(error -> log.error("令牌加入黑名单失败: token={}, error={}", 
                        token.substring(0, Math.min(20, token.length())) + "...", error.getMessage()))
                    .subscribe();
        } catch (Exception e) {
            log.error("令牌加入黑名单失败: token={}, error={}", token.substring(0, Math.min(20, token.length())) + "...", e.getMessage());
        }
    }

    @Override
    public boolean isBlacklisted(String token) {
        try {
            String key = BLACKLIST_PREFIX + token;
            return reactiveRedisTemplate.hasKey(key)
                    .doOnSuccess(blacklisted -> {
                        if (blacklisted) {
                            log.debug("令牌在黑名单中: token={}", token.substring(0, Math.min(20, token.length())) + "...");
                        }
                    })
                    .doOnError(error -> log.error("检查令牌黑名单失败: token={}, error={}", 
                        token.substring(0, Math.min(20, token.length())) + "...", error.getMessage()))
                    .onErrorReturn(false)
                    .block(); // 同步等待结果
        } catch (Exception e) {
            log.error("检查令牌黑名单失败: token={}, error={}", token.substring(0, Math.min(20, token.length())) + "...", e.getMessage());
            return false;
        }
    }

    @Override
    public void removeFromBlacklist(String token) {
        try {
            String key = BLACKLIST_PREFIX + token;
            reactiveRedisTemplate.delete(key)
                    .doOnSuccess(deleted -> log.info("令牌已从黑名单移除: token={}", 
                        token.substring(0, Math.min(20, token.length())) + "..."))
                    .doOnError(error -> log.error("从黑名单移除令牌失败: token={}, error={}", 
                        token.substring(0, Math.min(20, token.length())) + "...", error.getMessage()))
                    .subscribe();
        } catch (Exception e) {
            log.error("从黑名单移除令牌失败: token={}, error={}", token.substring(0, Math.min(20, token.length())) + "...", e.getMessage());
        }
    }

    @Override
    public void cleanExpiredTokens() {
        // Redis会自动清理过期的键，这里可以添加额外的清理逻辑
        log.info("清理过期令牌黑名单");
    }
}
